//
//  WHCodeAndDecodeTool.m
//  WHPersonalData
//
//  Created by shengmeng chen on 2019/5/21.
//  Copyright © 2019 mac. All rights reserved.
//

// GB18030 编码
#define kGBKEncoding CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000)

#import "WHCodeAndDecodeTool.h"
#import "WHKeyChainDataManager.h"
#import "wlcc_define.h"
#import "wlcc.h"
#include <stdio.h>
#include <stdlib.h>


@implementation WHCodeAndDecodeTool

-(instancetype)init
{
    self = [super init];
    
    if (self) {
        int ret = wlcc::Initialize(0, NULL);
        printf("init: %d\n", ret);
        ret = wlcc::Terminate();
        printf("term: %d\n", ret);

    }
    return self;
}

//产生随机数
+(int)genRandomWithlength:(int)length
{
    int ret = 0;
    struct wlcc::WLBLOB random;
    BlobInit(&random);
    ret = GenRandom(length,&random);
    if (ret != 0)
    {
        return-1;
    }
    BlobFree(&random);
    return ret;
}

// 对称加解密
+(int)genSymmKey
{

    int ret = 0;
    struct wlcc::WLBLOB key, enc, dec, data;
    BlobInit3(&key, &enc, &dec);
    BlobSetStr(&data, "abcdefg");
    
    ret = wlcc::Initialize(0, nil);
    if (ret != 0)
    {
        printf("init");
        return -1;
    }
    
    // 产生对称密钥
    ret = wlcc::GenSymmKey(CC_ALG_SYMM_DEF,CC_PROTECT_SYMM, &key);
    if (ret != 0)
    {
        printf("genSymmKey");
        release(&key, &enc, &dec,nil);
        return -1;
    }
    // 对称算法
    ret = wlcc::SymmEncrypt(CC_ALG_SYMM_DEF,CC_PROTECT_SYMM, &key, &data, &enc);
    if (ret != 0)
    {
        printf("symmEncrypt");
        release(&key, &enc, &dec,nil);
       return -1;
    }
    
    // 对称解密
    ret = wlcc::SymmDecrypt(CC_ALG_SYMM_DEF,CC_PROTECT_SYMM, &key, &enc, &dec);
    if (ret != 0)
    {
        printf("symmDecrypt");
        release(&key, &enc, &dec,nil);
       return -1;
    }
    
    NSLog(@"对称原文：%s", data.value);
    NSLog(@"对称密文：%s", enc.value);
    NSLog(@"对称解密：%s", dec.value);
    NSLog(@"对称原文长：%d", data.size);
    NSLog(@"对称密文长：%d", enc.size);
    NSLog(@"对称解密长：%d", dec.size);
    release(&key, &enc, &dec,nil);
    
    return ret;
}

// 非对称加解密
+(int)genAsymmKey
{
    int ret = 0;
    struct wlcc::WLBLOB pbk,pvk,enc,dec,data;
    BlobInit3(&pbk, &pvk, &enc);
    BlobInit(&dec);
    BlobSetStr(&data, "abcdefg");
    
    ret = wlcc::Initialize(0, nil);
    if (ret != 0)
    {
      printf("init");
    return -1;
    }
    // 产生对非对称密钥
    ret = wlcc::GenAsymmKey(CC_ALG_KEYX_DEF,CC_PROTECT_PRVK,CC_BITS_RSAK_DEF, &pbk, &pvk);
    if (ret != 0)
    {
        printf("GenAsymmKey");
        
        release(&pbk, &pvk, &enc, &dec);
        return -1;
    }
    // 非对称称算法
    ret = wlcc::PubkEncrypt(CC_ALG_KEYX_DEF, CC_PROTECT_NONE, &pbk, &data,&enc);
    if (ret != 0)
    {
        printf("PubkEncrypt");
        release(&pbk, &pvk, &enc, &dec);
        return -1;
   
    }
    // 非对称解密
    ret = wlcc::PrvkDecrypt(CC_ALG_KEYX_DEF,CC_PROTECT_PRVK,&pvk,&enc, &dec);
    if (ret != 0)
    {
        printf("PrvkDecrypt");
        release(&pbk, &pvk, &enc, &dec);
        return -1;
    }
    
    NSLog(@"非对称原文：%s", data.value);
    NSLog(@"非对称公钥：%s", pbk.value );
    NSLog(@"非对称私钥：%s", pvk.value);
    NSLog(@"非对称密文：%s", enc.value);
    NSLog(@"非对称解密：%s", dec.value);
    NSLog(@"非对称原文长：%d",data.size);
    NSLog(@"非对称密文长：%d",enc.size);
    NSLog(@"非对称解密长：%d",dec.size);
    
   //NSString *privateKey  = [[NSString alloc] initWithBytes:pbk.value length:pbk.size encoding:NSUTF8StringEncoding];
    
    NSData*publicKeyData = [[NSData alloc]initWithBytes:pbk.value length:pbk.size];
    NSString*publicKey = [publicKeyData base64EncodedStringWithOptions:0];
    NSData*privateKeyData = [[NSData alloc]initWithBytes:pvk.value length:pvk.size];
    NSString*privateKey = [privateKeyData base64EncodedStringWithOptions:0];
    release(&pbk, &pvk, &enc, &dec);
    
    return ret;
}

void WINAPI release( wlcc::WLBLOB*pbk,
                    wlcc::WLBLOB*pvk,
                     wlcc::WLBLOB*enc,
                      wlcc::WLBLOB*dec)
{
    BlobFree3(pbk, pvk,enc);
    BlobFree(dec);
    wlcc::Terminate();
}

// 签名验签
+(int)genSign
{
    int ret = 0;
    struct wlcc::WLBLOB pbk,pvk,sig,data;
    BlobInit3(&pbk, &pvk, &sig);
    BlobSetStr(&data, "abcdefg");

    ret = wlcc::Initialize(0, nil);
    if (ret != 0)
    {
        printf("init");
        return -1;
    }
    
    // 产生非对称密钥
    ret = wlcc::GenAsymmKey(CC_ALG_SIGN_DEF,CC_PROTECT_PRVK,CC_BITS_RSAK_DEF, &pbk,&pvk);
    if (ret != 0)
    {
        printf("GenAsymmKey");
        release(&pbk, &pvk,&sig,nil);
        return -1;
    }
    // 数字签名
    ret = wlcc::PrvkSignP1(CC_ALG_SIGN_DEF, CC_ALG_HASH_DEF,CC_PROTECT_PRVK,&pvk, &data,&sig);
    
    if (ret != 0)
    {
        printf("PrvkSignP1");
        release(&pbk, &pvk,&sig,nil);
        return -1;
    }
    
    // 签名验证
    ret = wlcc::PubkVerifyP1(CC_ALG_SIGN_DEF,CC_ALG_HASH_DEF, CC_PROTECT_NONE,&pbk, &data, &sig);
    
    if (ret != 0)
    {
        printf("PubkVerifyP1");
         release(&pbk, &pvk,&sig,nil);
        return -1;
    }
    
    NSLog(@"签名验签原文：%s", data.value);
    NSLog(@"签名验签私钥：%s", pvk.value);
    NSLog(@"签名验签公钥：%s", pbk.value);
    NSLog(@"签名：%s", sig.value);
    release(&pbk, &pvk,&sig,nil);
    return ret;
}
 //基于口令对称加解密
+(int)genPswdEncryptWithPswd:(NSString*)pswd
{
    
    int ret = 0;
    struct wlcc::WLBLOB enc,dec,data;
    BlobInit2(&enc, &dec);
    //BlobSetStr(&data, "abcdefg");
    char str[] = "abcdefg中国";
    int len = strlen(str);
    BlobSetByte(&data, (BYTE*)str, len + 1);
  
    ret = wlcc::Initialize(0, nil);
    if (ret != 0)
    {
        printf("init");
        return -1;
    }
    
   const char *pswdChar = [pswd cStringUsingEncoding:kGBKEncoding];
    
    //基于口令对称加密
    ret = wlcc::PswdEncrypt(CC_ALG_SYMM_DEF,pswdChar,&data,&enc);
    if (ret != 0)
    {
        printf("PswdEncrypt");
        release(&enc, &dec,nil,nil);
        return -1;
    }
    //基于口令对称解密
    ret = wlcc::PswdDecrypt(CC_ALG_SYMM_DEF,pswdChar, &enc, &dec);
    
    if (ret != 0)
    {
        printf("PswdDecrypt");
       release(&enc, &dec,nil,nil);
        return -1;
    }
    
    NSLog(@"基于口令对称原文：%s", data.value);
    NSLog(@"基于口令对称加密加密：%s",enc.value);
    NSLog(@"基于口令对称解密：%s", dec.value);
    release(&enc, &dec,nil,nil);
    return ret;
}

//产生公私和私钥，并进行口令加密
+(int)genPrivateKeyAndPublicKey:(NSString *_Nonnull*_Nonnull)publicKey withPrivateKey:(NSString *_Nullable*_Nullable)privateKey
{
    int ret = 0;
    struct wlcc::WLBLOB pbk,pvk,sig;
    BlobInit3(&pbk, &pvk, &sig);
    
    ret = wlcc::Initialize(0, nil);
    if (ret != 0)
    {
        printf("init");
        return -1 ;
    }
    // 产生非对称密钥
    ret = wlcc::GenAsymmKey(CC_ALG_SIGN_DEF,CC_PROTECT_PRVK,CC_BITS_RSAK_DEF, &pbk,&pvk);
    if (ret != 0)
    {
        printf("GenAsymmKey");
        release(&pbk, &pvk,&sig,nil);
         return -1 ;
    }
    //公钥
    NSData*publicKeyData = [[NSData alloc]initWithBytes:pbk.value length:pbk.size];
    *publicKey = [publicKeyData base64EncodedStringWithOptions:0];
    NSLog(@"publicKey =%@",*publicKey);
    NSString*deviceId= [WHKeyChainDataManager readUUID]; //读取
    NSString*pswd =[NSString stringWithFormat:@"%@wellhope123",deviceId];
    const char *pswdChar = [pswd cStringUsingEncoding:kGBKEncoding];
    //私钥
    NSData*temepPrivateKeyData = [[NSData alloc]initWithBytes:pvk.value length:pvk.size];
    NSString *temepPrivateKey = [temepPrivateKeyData base64EncodedStringWithOptions:0];
    NSLog(@"temepPrivateKey =%@",temepPrivateKey);
    
    *privateKey = temepPrivateKey;
    
    //对私钥口令对称加密
//   struct wlcc::WLBLOB enc;
//    BlobInit(&enc);
    
//    ret = wlcc::PswdEncrypt(CC_ALG_SYMM_DEF,pswdChar,&pvk,&enc);
//    if (ret != 0)
//    {
//        printf("PswdEncrypt");
//        release(&enc,nil,nil,nil);
//        return -1 ;
//    }
    
    //私钥
//    NSData*privateKeyData = [[NSData alloc]initWithBytes:enc.value length:enc.size];
//    *privateKey = [privateKeyData base64EncodedStringWithOptions:0];
    NSLog(@"privateKey =%@",*privateKey);
    release(&pbk, &pvk,&sig,nil);
    return ret;
}

//签名
+(int)signDataWithPrivateKey:(NSString*)privateKey withtDataString:(NSString*)dataString withPrivateKey:(NSString *_Nullable*_Nullable)sign
{
  
    int ret = 0;
    struct wlcc::WLBLOB enc,dec,data,sig,pbk,pvk;
    BlobInit3(&enc,&dec,&sig);
    BlobInit(&pbk);
    BlobInit(&pvk);
    
    NSData *privateKeyData = [[NSData alloc]initWithBase64EncodedString:privateKey options:NSDataBase64DecodingIgnoreUnknownCharacters];
    int privateKeylen =(int)privateKeyData.length;
    Byte *privateKeyByte = (Byte *)[privateKeyData bytes];
    BlobSetByte(&pvk, privateKeyByte,privateKeylen);
    //NSString *str =dataString;
    NSData* dataStringData = [dataString dataUsingEncoding:kGBKEncoding];
    int lenData =(int)dataStringData.length;
    Byte *valueData =(Byte*)dataStringData.bytes;
    BlobSetByte(&data, valueData,lenData);
    
   // NSString*publiceKey =@"MIGHAoGBAL9yQfOYhyBaN7PM/EfD1vNuVokeXror9qKlgyNDI1SeHCCQU80WEQq0miOseljFY/X0nadHM7lM75ow0yzrJ/ar8TrA6aKsyNk3iqSOvh9gXI6/ml/qwUvBjQ0VBbzQHD/egKcGWDTrB7omR61tAhfzDSk/cF+DG3QR1nHBGPSLAgED";
   
    //NSData *publiceKeyData = [[NSData alloc]initWithBase64EncodedString:publiceKey options:NSDataBase64DecodingIgnoreUnknownCharacters];

//    int publiceKeylen =(int)publiceKeyData.length;
//    Byte *tpubliceKeyByte = (Byte *)[publiceKeyData bytes];
//
//    BlobSetByte(&pbk,tpubliceKeyByte,publiceKeylen);
//
//    ret = wlcc::Initialize(0, nil);
//    if (ret != 0)
//    {
//        printf("init");
//        return -1;
//    }
    
    NSString*deviceId=[WHKeyChainDataManager readUUID];//读取//@"AFDB49CE-8B5A-4403-A14B-20C42A5F978F";
    NSString*pswd =[NSString stringWithFormat:@"%@wellhope123",deviceId];
    const char *pswdChar = [pswd cStringUsingEncoding:kGBKEncoding];
    //1.私钥基于口令对称解密
    ret = wlcc::PswdDecrypt(CC_ALG_SYMM_DEF,pswdChar,&pvk, &dec);
    if (ret != 0)
    {
        printf("PswdDecrypt");
        release(&enc, &dec,nil,nil);
        return -1;
    }

    //2. 数字签名
    ret = wlcc::PrvkSignP1(CC_ALG_SIGN_DEF, CC_ALG_HASH_DEF,CC_PROTECT_PRVK,&dec, &data,&sig);
    
    if (ret != 0)
    {
        printf("PrvkSignP1");
        release(&enc, &dec,&sig,nil);
        return -1;
    }
    
     NSLog(@"sig==%d",sig.size);
    // 签名验证
//   ret = wlcc::PubkVerifyP1(CC_ALG_SIGN_DEF,CC_ALG_HASH_DEF, CC_PROTECT_NONE,&pbk, &data, &sig);
//
//    if (ret != 0)
//    {
//        printf("PubkVerifyP1");
//        return -1;
//    }

    NSData*sigData = [[NSData alloc]initWithBytes:sig.value length:sig.size];
    *sign = [sigData base64EncodedStringWithOptions:0];
    NSLog(@"signData =%@",*sign);
    release(&enc, &dec,&sig,nil);
    return ret;
}

//签名和验签
//+(int)testSignDataWithPrivateKey:(NSString*)privateKey withtDataString:(NSString*)dataString withPrivateKey:(NSString *)publiceKey withSign:(NSString *_Nullable*_Nullable)sign
//{
//    
//    int ret = 0;
//    struct wlcc::WLBLOB enc,dec,data,sig,pbk,pvk;
//    BlobInit3(&enc,&dec,&sig);
//    BlobInit(&pbk);
//    BlobInit(&pvk);
//    
//    NSData *privateKeyData = [[NSData alloc]initWithBase64EncodedString:privateKey options:NSDataBase64DecodingIgnoreUnknownCharacters];
//    
//    int privateKeylen =(int)privateKeyData.length;
//    Byte *privateKeyByte = (Byte *)[privateKeyData bytes];
//    
//    BlobSetByte(&pvk, privateKeyByte,privateKeylen);
//    
//    //NSString *str =dataString;
//    NSData* dataStringData = [dataString dataUsingEncoding:kGBKEncoding];
//    
//    int lenData =(int)dataStringData.length;
//    Byte *valueData =(Byte*)dataStringData.bytes;
//    
//    BlobSetByte(&data, valueData,lenData);
//    
//    // NSString*publiceKey =@"MIGHAoGBAL9yQfOYhyBaN7PM/EfD1vNuVokeXror9qKlgyNDI1SeHCCQU80WEQq0miOseljFY/X0nadHM7lM75ow0yzrJ/ar8TrA6aKsyNk3iqSOvh9gXI6/ml/qwUvBjQ0VBbzQHD/egKcGWDTrB7omR61tAhfzDSk/cF+DG3QR1nHBGPSLAgED";
//    
//    
//    NSData *publiceKeyData = [[NSData alloc]initWithBase64EncodedString:publiceKey options:NSDataBase64DecodingIgnoreUnknownCharacters];
//    
//        int publiceKeylen =(int)publiceKeyData.length;
//        Byte *tpubliceKeyByte = (Byte *)[publiceKeyData bytes];
//    
//        BlobSetByte(&pbk,tpubliceKeyByte,publiceKeylen);
//    
//        ret = wlcc::Initialize(0, nil);
//        if (ret != 0)
//        {
//            printf("init");
//            return -1;
//        }
//    
//    NSString*deviceId=[WHKeyChainDataManager readUUID];//读取//@"AFDB49CE-8B5A-4403-A14B-20C42A5F978F";
//    NSString*pswd =[NSString stringWithFormat:@"%@wellhope123",deviceId];
//    
//    const char *pswdChar = [pswd cStringUsingEncoding:kGBKEncoding];
//    
//    //1.私钥基于口令对称解密
//    ret = wlcc::PswdDecrypt(CC_ALG_SYMM_DEF,pswdChar,&pvk, &dec);
//    
//    if (ret != 0)
//    {
//        printf("PswdDecrypt");
//        release(&enc, &dec,nil,nil);
//        return -1;
//    }
//    
//    //2. 数字签名
//    ret = wlcc::PrvkSignP1(CC_ALG_SIGN_DEF, CC_ALG_HASH_DEF,CC_PROTECT_PRVK,&dec, &data,&sig);
//    
//    if (ret != 0)
//    {
//        printf("PrvkSignP1");
//        release(&enc, &dec,&sig,nil);
//        return -1;
//    }
//    
//    NSLog(@"sig==%d",sig.size);
//    
//    // 签名验证
//       ret = wlcc::PubkVerifyP1(CC_ALG_SIGN_DEF,CC_ALG_HASH_DEF, CC_PROTECT_NONE,&pbk, &data, &sig);
//    
//        if (ret != 0)
//        {
//            printf("PubkVerifyP1");
//            return -1;
//        }
//    
//    NSData*sigData = [[NSData alloc]initWithBytes:sig.value length:sig.size];
//    *sign = [sigData base64EncodedStringWithOptions:0];
//    NSLog(@"signData =%@",*sign);
//    release(&enc, &dec,&sig,nil);
//    return ret;
//}

@end
